package com.aabte.springcloudlearn.ribbonhystrixcustomerdemo.service;

import com.aabte.springcloudlearn.common.beans.User;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCollapser;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.junit.Assert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;

/**
 * @author Daniel
 */
@Slf4j
@Service
public class UserCustomerService {

    @Autowired
    private RestTemplate restTemplate;

    public List<User> findAll(List<Long> ids) {
        log.info("Start findAll. ids: {}", ids);

        UriComponentsBuilder uriComponentsBuilder = UriComponentsBuilder.fromHttpUrl("http://hello-service/user");
        if (ids != null) {
            uriComponentsBuilder.queryParam("ids", StringUtils.join(ids, ","));
        }
        String url = uriComponentsBuilder.build().toString();

        User[] users = restTemplate.getForObject(url, User[].class);

        List<User> result = Arrays.asList(users);

        log.info("End findAll. result: {}", result);
        return result;
    }

    public User findOne(Long id) {
        log.info("Start findOne. id: {}", id);
        Map<String, Object> urlParams = new HashMap<>(1);
        urlParams.put("id", id);
        User user = restTemplate.getForObject("http://hello-service/user/{id}", User.class, urlParams);
        log.info("End findOne. user: {}", user);
        return user;
    }

    public Boolean registerUser(User user) {
        log.info("Start registerUser. user: {}", user);
        Boolean result = restTemplate.postForEntity("http://hello-service/user", user, Boolean.class).getBody();
        log.info("End registerUser. result: {}", result);
        return result;
    }

    public Boolean updateUser(User user) {
        log.info("Start updateUser. user: {}", user);
        restTemplate.put("http://hello-service/user", user);
        log.info("End updateUser.");
        return true;
    }

    public Boolean deleteUser(Long id) {
        log.info("Start deleteUser. id: {}", id);
        restTemplate.delete("http://hello-service/user/{id}", id);
        log.info("End deleteUser.");
        return true;
    }

    @HystrixCollapser(
            batchMethod = "findAllByAnnotation",
            collapserProperties = {
                    @HystrixProperty(name = "timerDelayInMilliseconds", value = "5000")
            }
    )
    public Future<User> findOneByAnnotation(Long id) {
        log.info("Start findOneByAnnotation. id: {}", id);
        // 不会进入这个方法
        Assert.fail();
        return null;
    }

    /**
     * 批量查询方法
     */
    @HystrixCommand
    public List<User> findAllByAnnotation(List<Long> ids) {
        log.info("Start findAllByAnnotation. ids: {}", ids);

        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("http://hello-service/user");
        if (ids != null) {
            builder.queryParam("ids", StringUtils.join(ids, ","));
        }
        String url = builder.build().toString();

        User[] users = restTemplate.getForObject(url, User[].class);
        List<User> result = Arrays.asList(users);

        log.info("End findAllByAnnotation. result: {}", result);
        return result;
    }
}
